package com.by.flutter_init

import android.Manifest
import android.app.Activity
import android.content.pm.PackageManager
import android.util.Log
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import com.amap.api.location.AMapLocation
import com.amap.api.location.AMapLocationClient
import com.amap.api.location.AMapLocationClientOption
import com.amap.api.location.AMapLocationListener
import com.amap.api.services.core.LatLonPoint
import com.amap.api.services.core.ServiceSettings
import com.amap.api.services.geocoder.GeocodeSearch
import com.amap.api.services.geocoder.RegeocodeAddress
import com.amap.api.services.geocoder.RegeocodeQuery
import com.amap.api.services.geocoder.RegeocodeResult
import io.flutter.embedding.engine.plugins.FlutterPlugin
import io.flutter.embedding.engine.plugins.activity.ActivityAware
import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding
import io.flutter.plugin.common.MethodCall
import io.flutter.plugin.common.MethodChannel
import io.flutter.plugin.common.MethodChannel.MethodCallHandler
import io.flutter.plugin.common.MethodChannel.Result

/**
 * 高德地图定位插件
 * 
 * 提供定位、逆地理编码等功能
 * 参考 MyApplication2 项目实现
 */
class AmapLocationPlugin : FlutterPlugin, MethodCallHandler, ActivityAware {
    
    companion object {
        private const val TAG = "AmapLocationPlugin"
        private const val CHANNEL_NAME = "com.playtruly.amap_location"
    }
    
    private lateinit var channel: MethodChannel
    private var activity: Activity? = null
    private var applicationContext: android.content.Context? = null
    private var locationClient: AMapLocationClient? = null
    private var geocodeSearch: GeocodeSearch? = null
    
    // 🔥 添加标志位：记录高德SDK是否已完成隐私合规初始化
    private var isAmapPrivacyInitialized = false
    
    // Flutter Plugin 生命周期
    override fun onAttachedToEngine(binding: FlutterPlugin.FlutterPluginBinding) {
        Log.d(TAG, "🗺️ =============== AmapLocationPlugin onAttachedToEngine ===============")
        
        channel = MethodChannel(binding.binaryMessenger, CHANNEL_NAME)
        channel.setMethodCallHandler(this)
        applicationContext = binding.applicationContext
        
        // ✅ 移除这里的高德SDK初始化代码
        // ✅ 等待Flutter端调用 initAMapPrivacy() 方法
        
        Log.d(TAG, "✅ Platform Channel 注册成功: $CHANNEL_NAME")
        Log.d(TAG, "⏳ 等待用户同意隐私政策后初始化高德SDK...")
    }
    
    override fun onDetachedFromEngine(binding: FlutterPlugin.FlutterPluginBinding) {
        Log.d(TAG, "🗑️ AmapLocationPlugin onDetachedFromEngine")
        channel.setMethodCallHandler(null)
        stopLocation()
    }
    
    // Activity 生命周期
    override fun onAttachedToActivity(binding: ActivityPluginBinding) {
        Log.d(TAG, "📱 AmapLocationPlugin onAttachedToActivity")
        activity = binding.activity
        initLocationClient()
        initGeocodeSearch()
    }
    
    override fun onDetachedFromActivity() {
        Log.d(TAG, "📱 AmapLocationPlugin onDetachedFromActivity")
        activity = null
        stopLocation()
    }
    
    override fun onReattachedToActivityForConfigChanges(binding: ActivityPluginBinding) {
        activity = binding.activity
    }
    
    override fun onDetachedFromActivityForConfigChanges() {
        // 配置变化时不销毁定位客户端
    }
    
    // 初始化定位客户端
    private fun initLocationClient() {
        try {
            Log.d(TAG, "🎯 初始化高德定位客户端...")
            
            // 🔥 优先使用activity，如果activity为null则使用applicationContext
            val context = activity?.applicationContext ?: applicationContext
            
            if (context == null) {
                Log.e(TAG, "❌ Context为空，无法初始化定位客户端")
                return
            }
            
            // 🔥 如果已经初始化，先销毁旧的
            if (locationClient != null) {
                Log.d(TAG, "⚠️ 检测到已有定位客户端，先销毁")
                locationClient?.onDestroy()
                locationClient = null
            }
            
            locationClient = AMapLocationClient(context)
            
            Log.d(TAG, "✅ 高德定位客户端初始化成功")
        } catch (e: Exception) {
            Log.e(TAG, "❌ 初始化定位客户端失败: ${e.message}")
            e.printStackTrace()
        }
    }
    
    // 初始化逆地理编码搜索
    private fun initGeocodeSearch() {
        activity?.let { act ->
            try {
                geocodeSearch = GeocodeSearch(act.applicationContext)
                Log.d(TAG, "✅ 逆地理编码搜索初始化成功")
            } catch (e: Exception) {
                Log.e(TAG, "❌ 初始化逆地理编码搜索失败: ${e.message}")
            }
        }
    }
    
    // 处理 Flutter 方法调用
    override fun onMethodCall(call: MethodCall, result: Result) {
        Log.d(TAG, "📞 收到 Flutter 调用: ${call.method}")
        
        when (call.method) {
            "initAMapPrivacy" -> initAMapPrivacy(result)  // 🔥 新增方法
            "startLocation" -> startLocation(call, result)
            "stopLocation" -> stopLocation(result)
            "checkPermissions" -> checkPermissions(result)
            "reverseGeocode" -> reverseGeocode(call, result)
            else -> result.notImplemented()
        }
    }
    
    /**
     * 🔥 初始化高德地图隐私合规（由Flutter端在用户同意隐私政策后调用）
     */
    private fun initAMapPrivacy(result: Result) {
        Log.d(TAG, "🔐 =============== 初始化高德SDK隐私合规 ===============")
        
        // 防止重复初始化
        if (isAmapPrivacyInitialized) {
            Log.d(TAG, "⚠️ 高德SDK隐私合规已初始化，跳过重复初始化")
            result.success(mapOf(
                "success" to true,
                "message" to "高德SDK隐私合规已初始化"
            ))
            return
        }
        
        try {
            val context = applicationContext ?: activity?.applicationContext
            
            if (context == null) {
                Log.e(TAG, "❌ Context为空，无法初始化高德SDK")
                result.success(mapOf(
                    "success" to false,
                    "message" to "Context为空"
                ))
                return
            }
            
            // 🔥 在用户同意隐私政策后，才调用高德SDK的隐私合规API
            AMapLocationClient.updatePrivacyShow(context, true, true)
            AMapLocationClient.updatePrivacyAgree(context, true)
            
            // 设置服务配置
            ServiceSettings.updatePrivacyShow(context, true, true)
            ServiceSettings.updatePrivacyAgree(context, true)
            
            isAmapPrivacyInitialized = true
            
            Log.d(TAG, "✅ 高德SDK隐私合规配置完成")
            Log.d(TAG, "✅ 现在可以安全地使用高德定位服务了")
            
            result.success(mapOf(
                "success" to true,
                "message" to "高德SDK隐私合规配置完成"
            ))
        } catch (e: Exception) {
            Log.e(TAG, "❌ 高德SDK隐私合规配置失败: ${e.message}")
            result.success(mapOf(
                "success" to false,
                "message" to "配置失败: ${e.message}"
            ))
        }
    }
    
    /**
     * 开始定位（增加隐私合规检查）
     */
    private fun startLocation(call: MethodCall, result: Result) {
        Log.d(TAG, "🎯 =============== 开始高德定位 ===============")
        
        // 🔥 检查是否已完成隐私合规初始化
        if (!isAmapPrivacyInitialized) {
            Log.e(TAG, "❌ 高德SDK隐私合规未初始化，拒绝定位请求")
            result.success(mapOf(
                "success" to false,
                "errorCode" to -99,
                "errorMessage" to "高德SDK隐私合规未初始化，请先获取用户同意"
            ))
            return
        }
        
        val isOnceLocation = call.argument<Boolean>("isOnceLocation") ?: true
        Log.d(TAG, "📍 定位模式: ${if (isOnceLocation) "单次定位" else "持续定位"}")
        
        // 检查权限
        if (!hasLocationPermission()) {
            Log.e(TAG, "❌ 缺少定位权限")
            result.success(mapOf(
                "success" to false,
                "errorCode" to 12,
                "errorMessage" to "缺少定位权限"
            ))
            return
        }
        
        // 🔥 确保定位客户端已初始化
        if (locationClient == null) {
            Log.w(TAG, "⚠️ 定位客户端未初始化，尝试重新初始化...")
            initLocationClient()
            
            // 再次检查
            if (locationClient == null) {
                Log.e(TAG, "❌ 定位客户端初始化失败")
                result.success(mapOf(
                    "success" to false,
                    "errorCode" to -2,
                    "errorMessage" to "定位客户端初始化失败"
                ))
                return
            }
        }
        
        try {
            // 配置定位选项（参考 MyApplication2）
            val option = AMapLocationClientOption().apply {
                locationMode = AMapLocationClientOption.AMapLocationMode.Hight_Accuracy
                this.isOnceLocation = isOnceLocation  // 使用 this 明确指定是属性赋值
                interval = 2000  // 定位间隔
                httpTimeOut = 30000  // 超时时间
                isNeedAddress = true  // 需要地址信息
                isLocationCacheEnable = true  // 启用缓存
            }
            
            locationClient?.setLocationOption(option)
            Log.d(TAG, "✅ 定位选项配置完成")
            
            // 🔥 使用标志位确保result只被调用一次
            var hasInvokedResult = false
            
            // 设置定位监听
            locationClient?.setLocationListener { location ->
                Log.d(TAG, "📨 收到定位回调")
                if (!hasInvokedResult) {
                    hasInvokedResult = true
                    handleLocationResult(location, result)
                    
                    // 🔥 如果是单次定位，回调后立即停止定位
                    if (isOnceLocation) {
                        locationClient?.stopLocation()
                        Log.d(TAG, "🛑 单次定位完成，已自动停止定位")
                    }
                } else {
                    Log.d(TAG, "⚠️ 收到重复定位回调，已忽略（result已返回）")
                }
            }
            
            Log.d(TAG, "✅ 定位监听器设置完成")
            
            // 启动定位
            locationClient?.startLocation()
            Log.d(TAG, "✅ 定位已启动，等待回调...")
            
        } catch (e: Exception) {
            Log.e(TAG, "❌ 启动定位失败: ${e.message}")
            e.printStackTrace()
            result.success(mapOf(
                "success" to false,
                "errorCode" to -1,
                "errorMessage" to "启动定位失败: ${e.message}"
            ))
        }
    }
    
    /**
     * 处理定位结果
     */
    private fun handleLocationResult(location: AMapLocation?, result: Result) {
        Log.d(TAG, "📨 收到定位结果")
        
        if (location == null) {
            Log.e(TAG, "❌ 定位结果为空")
            result.success(mapOf(
                "success" to false,
                "errorCode" to -1,
                "errorMessage" to "定位结果为空"
            ))
            return
        }
        
        if (location.errorCode == 0) {
            // 定位成功
            val resultMap = mutableMapOf<String, Any?>(
                "success" to true,
                "latitude" to location.latitude,
                "longitude" to location.longitude,
                "accuracy" to location.accuracy.toDouble(),
                "altitude" to location.altitude,
                "bearing" to location.bearing.toDouble(),
                "speed" to location.speed.toDouble(),
                "timestamp" to location.time,
                "address" to location.address,
                "country" to location.country,
                "province" to location.province,
                "city" to location.city,
                "district" to location.district,
                "street" to location.street,
                "streetNumber" to location.streetNum,
                "poiName" to location.poiName,
                "aoiName" to location.aoiName,
                "provider" to location.provider,
                "locationType" to location.locationType
            )
            
            Log.d(TAG, "✅ 定位成功!")
            Log.d(TAG, "📍 坐标: ${location.latitude}, ${location.longitude}")
            Log.d(TAG, "🎯 精度: ${location.accuracy}m")
            Log.d(TAG, "📍 地址: ${location.address}")
            
            result.success(resultMap)
        } else {
            // 定位失败
            Log.e(TAG, "❌ 定位失败: ${location.errorInfo} (${location.errorCode})")
            result.success(mapOf(
                "success" to false,
                "errorCode" to location.errorCode,
                "errorMessage" to location.errorInfo
            ))
        }
    }
    
    /**
     * 停止定位
     */
    private fun stopLocation(result: Result? = null) {
        try {
            locationClient?.stopLocation()
            locationClient?.onDestroy()
            locationClient = null
            
            Log.d(TAG, "🛑 定位已停止")
            
            result?.success(mapOf(
                "success" to true
            ))
        } catch (e: Exception) {
            Log.e(TAG, "❌ 停止定位失败: ${e.message}")
            result?.success(mapOf(
                "success" to false,
                "errorMessage" to e.message
            ))
        }
    }
    
    /**
     * 检查定位权限
     */
    private fun checkPermissions(result: Result) {
        val hasPermission = hasLocationPermission()
        
        Log.d(TAG, "🔍 检查定位权限: $hasPermission")
        
        result.success(mapOf(
            "hasPermissions" to hasPermission,
            "message" to if (hasPermission) "权限已授予" else "缺少定位权限"
        ))
    }
    
    /**
     * 逆地理编码（坐标转地址）
     */
    private fun reverseGeocode(call: MethodCall, result: Result) {
        Log.d(TAG, "🌐 =============== 开始逆地理编码 ===============")
        
        val latitude = call.argument<Double>("latitude")
        val longitude = call.argument<Double>("longitude")
        
        if (latitude == null || longitude == null) {
            Log.e(TAG, "❌ 坐标参数无效")
            result.success(mapOf(
                "success" to false,
                "errorCode" to -1,
                "errorMessage" to "坐标参数无效"
            ))
            return
        }
        
        Log.d(TAG, "📍 目标坐标: $latitude, $longitude")
        
        try {
            val latLonPoint = LatLonPoint(latitude, longitude)
            val query = RegeocodeQuery(latLonPoint, 200f, GeocodeSearch.AMAP)
            
            geocodeSearch?.setOnGeocodeSearchListener(object : com.amap.api.services.geocoder.GeocodeSearch.OnGeocodeSearchListener {
                override fun onRegeocodeSearched(regeocodeResult: RegeocodeResult?, errorCode: Int) {
                    if (errorCode == 1000 && regeocodeResult != null) {
                        val address: RegeocodeAddress = regeocodeResult.regeocodeAddress
                        
                        val resultMap = mapOf(
                            "success" to true,
                            "latitude" to latitude,
                            "longitude" to longitude,
                            "address" to address.formatAddress,
                            "country" to address.country,
                            "province" to address.province,
                            "city" to address.city,
                            "district" to address.district,
                            "street" to (address.streetNumber?.street ?: ""),
                            "streetNumber" to (address.streetNumber?.number ?: ""),
                            "poiName" to (address.pois?.getOrNull(0)?.title ?: ""),
                            "aoiName" to (address.aois?.getOrNull(0)?.aoiName ?: "")  // 修复：使用 aoiName 属性而不是 name
                        )
                        
                        Log.d(TAG, "✅ 逆地理编码成功: ${address.formatAddress}")
                        result.success(resultMap)
                    } else {
                        Log.e(TAG, "❌ 逆地理编码失败: errorCode=$errorCode")
                        result.success(mapOf(
                            "success" to false,
                            "errorCode" to errorCode,
                            "errorMessage" to "逆地理编码失败"
                        ))
                    }
                }
                
                override fun onGeocodeSearched(p0: com.amap.api.services.geocoder.GeocodeResult?, p1: Int) {
                    // 不需要实现
                }
            })
            
            geocodeSearch?.getFromLocationAsyn(query)
            
        } catch (e: Exception) {
            Log.e(TAG, "❌ 逆地理编码异常: ${e.message}")
            result.success(mapOf(
                "success" to false,
                "errorCode" to -1,
                "errorMessage" to "逆地理编码异常: ${e.message}"
            ))
        }
    }
    
    /**
     * 检查是否有定位权限
     */
    private fun hasLocationPermission(): Boolean {
        val activity = this.activity ?: return false
        
        val fineLocation = ContextCompat.checkSelfPermission(
            activity, 
            Manifest.permission.ACCESS_FINE_LOCATION
        ) == PackageManager.PERMISSION_GRANTED
        
        val coarseLocation = ContextCompat.checkSelfPermission(
            activity, 
            Manifest.permission.ACCESS_COARSE_LOCATION
        ) == PackageManager.PERMISSION_GRANTED
        
        return fineLocation || coarseLocation
    }
}

